package com.component.api.model.dto;

import cn.hutool.core.util.StrUtil;
import com.component.api.function.FormulaFunction;
import com.component.api.function.OperationFunction;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.script.*;
import java.io.Serializable;

/**
 * 描述：
 * 缺省值替换
 * @author xianggj
 * @Date 2021/11/29 14:00
 **/
@Data
@NoArgsConstructor
public class DefaultColumnDTO extends ColumnDTO implements Serializable {
    private static final long serialVersionUID = -1L;
    /**
     * 规则类型
     */
    public static final String AUTO = "auto";
    @Deprecated
    public static final String CALC = "calc";
    public static final String RELY = "rely";
    private String rule;

    /**
     * 填充公式
     */
    private String ruleFormula;

    /**
     * 规则值
     * val:取值,field:字段,min:最小,max:最大
     * inter:插值填充,avg:均值填充,mid:取中值,min:取最小值,max:取最大值
     */
    public static final String INTER = "inter";
    public static final String AVG = "avg";
    public static final String MID = "mid";
    public static final String MIN = "min";
    public static final String MAX = "max";
    private String ruleVal;

    /**
     * 依赖规则
     * val:取值,field:字段,min:最小,max:最大
     */
    private Rely relyVal;
    /**
     * 消歧规则
     */
    @Data
    @NoArgsConstructor
    public static class Rely implements Serializable  {
        private static final long serialVersionUID = -1L;
        /**
         * 取值 (都整double,到时候再转)
         */
        private Double val;

        /**
         * 字段
         */
        private String field;

        /**
         * 字段坐标
         */
        private int index;

        /**
         * 最小
         */
        private Double min;
        /**
         * 最大
         */
        private Double max;

        /**
         * 获取计算公式
         *  这里只做公式的处理，其他处理在类实现中整
         * @return
         */
        public OperationFunction getFunction(){
            if (val == null) {
                return e -> null;
            }
            if (max == null){
                max = Double.MAX_VALUE;
            }
            if (min == null){
                min = Double.MIN_VALUE;
            }
            return e -> {
                if (e >= min && e < max){
                    return val;
                }
                return null;
            };

        }
    }

    /**
     * 获取计算公式
     *  这里只做公式的处理，其他处理在类实现中整
     * @return
     */
    @Deprecated
    public FormulaFunction getFunction(){
        if (StrUtil.isBlank(ruleFormula) || StrUtil.isBlank(rule)) {
            return e -> e;
        }
        if (CALC.equals(rule)){
            return e -> {
                ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
                Compilable compilable = (Compilable) engine;
                Bindings bindings = engine.createBindings(); //Local级别的Binding
                CompiledScript JSFunction = null; //解析编译脚本函数
                try {
                    JSFunction = compilable.compile(ruleFormula);
                    bindings.put("F", e);
                    return JSFunction.eval(bindings);
                } catch (ScriptException ex) {
                    ex.printStackTrace();
                }
                return e;
            };
        }

        return e->e;

    }

}
